<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button id="replay">重放</button>
    <script>
      //基本写法
      // 模拟拳皇的场景
      const Ryu = {
        attack: () => {
          console.log("攻击 => ");
        },
        defense: () => {
          console.log("防御 => ");
        },
        jump: () => {
          console.log("跳跃 => ");
        },
        crouch: () => {
          console.log("蹲下 => ");
        },
      };

      const commands = {
        119: "jump", // W
        115: "crouch", // S
        97: "defense", // A
        100: "attack", // D
      };

      // 创建命令
      const makeCommand = (receiver, state) => receiver[state];

      const commandStack = [];
      document.onkeypress = function (e) {
        const command = makeCommand(Ryu, commands[e.keyCode]);
        if (command) {
          command(); // 执行命令
          commandStack.push(command);
        }
      };
      // 回放
      const replay = document.getElementById("replay");
      replay.onclick = function (e) {
        let command;
        while ((command = commandStack.shift())) {
          command();
        }
      };

      //宏命令是一组命令的集合，通过执行宏命令的方式，可以一次执行一批命令。
      //批量执行， 相当于一键操作。想象一下，家 里有一个万能遥控器，每天回家的时候，
      //只要按一个特别的按钮，它就会帮我们关上房间门，顺便打开电脑并登录 QQ。
      const commandSet = {
        closeDoor: () => {
          console.log("关上房门 => ");
        },
        openPc: () => {
          console.log("打开电脑 => ");
        },
        openQQ: () => {
          console.log("打开qq1 => ");
        },
      };

      class MacroCommand {
        commandList = [];
        add = (command) => this.commandList.push(command);
        execute = () => this.commandList.forEach((item) => item());
        replay = () => {
          let command;
          while ((command = this.commandList.shift())) {
            command();
          }
        };
        print = () => console.log("this.commandList => ", this.commandList);
      }

      const mc = new MacroCommand();
      const { closeDoor, openPc, openQQ } = commandSet;
      mc.add(closeDoor);
      mc.add(openPc);
      mc.add(openQQ);
      mc.print();
      setTimeout(mc.execute, 2000);
      setTimeout(mc.replay, 5000);
    </script>
  </body>
</html>
